This setup is for UNPRIVILEGED containers running directly under the user. This is the most secure way to run LXC containers, because the root account is not directly involved.
Taken from https://wiki.archlinux.org/title/Linux_Containers#Required_software
sudo pacman -Syu lxc arch-install-scripts
Taken from: https://linuxcontainers.org/lxc/getting-started/
echo "$(id -un) veth lxcbr0 10" | sudo tee -a /etc/lxc/lxc-usernet
Taken from https://linuxcontainers.org/lxc/getting-started/
mkdir ~/.config/lxc
cp /etc/lxc/default.conf ~/.config/lxc/default.conf
sudo nano ~/.config/lxc/default.conf
and append the following lines:
lxc.idmap = u 0 100000 65536
lxc.idmap = g 0 100000 65536
These values have to match those found in /etc/subuid
and /etc/subgid
. In Arch, these should already be set correctly.This fixes the 'Permission denied - Could not access /home/
setfacl -m u:100000:x /home/<username>
There are two options here. If you don't neet network, you can follow these steps.
Since the file under /etc/default/lxc-net
does not exist, we set the usage of the LXC bridge to true here:
sudo nano /etc/default/lxc
USE_LXC_BRIDGE="true" # overridden in lxc-net
And restart the lxc-net service to start and enable the LXC bridge:
sudo systemctl start lxc-net
sudo systemctl enable lxc-net
Taken from: https://wiki.archlinux.org/title/Linux_Containers Create the configuration for the network bridge and fill the relevant info:
sudo nano /etc/default/lxc-net
And fill this:
# Leave USE_LXC_BRIDGE as "true" if you want to use lxcbr0 for your
# containers. Set to "false" if you'll use virbr0 or another existing
# bridge, or mavlan to your host's NIC.
USE_LXC_BRIDGE="true"
# If you change the LXC_BRIDGE to something other than lxcbr0, then
# you will also need to update your /etc/lxc/default.conf as well as the
# configuration (/var/lib/lxc/<container>/config) for any containers
# already created using the default config to reflect the new bridge
# name.
# If you have the dnsmasq daemon installed, you'll also have to update
# /etc/dnsmasq.d/lxc and restart the system wide dnsmasq daemon.
LXC_BRIDGE="lxcbr0"
LXC_ADDR="10.0.3.1"
LXC_NETMASK="255.255.255.0"
LXC_NETWORK="10.0.3.0/24"
LXC_DHCP_RANGE="10.0.3.31,10.0.3.254"
LXC_DHCP_MAX="253"
# Uncomment the next line if you'd like to use a conf-file for the lxcbr0
# dnsmasq. For instance, you can use 'dhcp-host=mail1,10.0.3.100' to have
# container 'mail1' always get ip address 10.0.3.100.
#LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf
# Uncomment the next line if you want lxcbr0's dnsmasq to resolve the .lxc
# domain. You can then add "server=/lxc/10.0.3.1' (or your actual $LXC_ADDR)
# to your system dnsmasq configuration file (normally /etc/dnsmasq.conf,
# or /etc/NetworkManager/dnsmasq.d/lxc.conf on systems that use NetworkManager).
# Once these changes are made, restart the lxc-net and network-manager services.
# 'container1.lxc' will then resolve on your host.
#LXC_DOMAIN="lxc"
Additional Info:
10.0.3.2 - 10.0.3.254
defined. We changed it to 10.0.3.31 - 10.0.3.254
10.0.3.1
as LXC_ADDR
if the default or the range above is usedsudo systemctl status lxc-net
some info about the bridge can be seenIf you are happy with the configuration, (re)start the lxc-net service to start:
sudo systemctl restart lxc-net
Enable the LXC bridge, if it is not already enabled:
sudo systemctl enable lxc-net
If the container doesn't get an IPv4, we can set a fixed IPv4 address to circumvent the issue.
[!NOTE] This step can only be done after the container was created and started.
[!IMPORTANT] The following example is for a Debian container which is using systemd-networkd as a networking service.
While attached to the container, edit the following config:
sudo vi /etc/systemd/network/eth0.network
And instead of using DHCP put a fixed IPv4 in it:
[Match]
Name=eth0
[Network]
#DHCP=true # Disabled because of our fixed IPv4
Address=10.0.3.2/24
Gateway=10.0.3.1
DNS=1.1.1.1
[DHCPv4]
UseDomains=true
[DHCP]
ClientIdentifier=mac
This will collide if another container actually gets an IPv4 and it is the same as the here defined one.
systemd-run --unit=my-unit --user --scope -p "Delegate=yes" -- lxc-create --name mycontainer --template download
You can select a distribution, release version and architecture interactively.
If you want to specify the location where the container gets created, use the --lxcpath
option. When set, this path has to be passed along all future lxc-* commands for it to find the container.
An example to create the container inside the /some/path/lxc-containers
folder:
systemd-run --unit=my-unit --user --scope -p "Delegate=yes" -- lxc-create --lxcpath "/some/path/lxc-containers" --name mycontainer --template download
To run the container (and attaching via the -F
option), run:
systemd-run --unit=my-unit --user --scope -p "Delegate=yes" -- lxc-start -F --lxcpath=/some/path/lxc-containers --name mycontainer
The --lxcpath
option can be omitted to use the default container location.
Note that you cannot login here since no password is set out of the box.
Stop the container with:
systemd-run --unit=my-unit --user --scope -p "Delegate=yes" -- lxc-stop --lxcpath=/some/path/lxc-containers --name mycontainer
The --lxcpath
option can be omitted to use the default container location.
For containers in the default location:
lxc-ls --fancy --lxcpath=/some/path/lxc-containers
The --lxcpath
option can be omitted to use the default container location.
To delete the container:
systemd-run --unit=my-unit --user --scope -p "Delegate=yes" -- lxc-destroy --lxcpath=/some/path/lxc-containers --name mycontainer
The --lxcpath
option can be omitted to use the default container location.
We cannot login when the container was freshly created, but we can execute commands directly from outside the container.
This executes uname -a
inside the LXC container:
lxc-execute --lxcpath=/some/path/lxc-containers --name=mycontainer -- uname -a
The --lxcpath
option can be omitted to use the default container location.
To further interact with the container, for example to set a username and password, you need to be attached as root to the container. For attaching, you HAVE to start it using the start script above. If you used virt-manager to start it, it doesn't work.
We can do that as follows:
lxc-attach --lxcpath=/some/path/lxc-containers --name=mycontainer
For some reason, the useradd command is not in the PATH (at least in the debian container template), so we need to execute it with the full path:
/usr/sbin/useradd user
And to change its password:
passwd user
And to add him to the sudoers list:
/usr/sbin/usermod -aG sudo user
For some reason, the console when using the -F
option is kinda broken.
We can attach (see attaching to container) and then login as our created user:
su - user